﻿/* ------------------------------------------------------------------------------------------------
 * 
 *      Copyright 2010 H. Stoll GmbH & Co. KG    All Rights Reserved.
 * 
 *      PROJECT         : PHX
 *      MODULE          : Phx.Components.UI.WindowBase
 *      
 *      DESCRIPTION     : ActionCommandBase Implementation
 *      
 *      AUTHOR          : MTW
 * --------------------------------------------------------------------------------------------- */

namespace CookPlan.Command
{
    using System;
    using System.ComponentModel;
    using System.Linq.Expressions;
    using System.Windows.Input;

    /// -------------------------------------------------------------------------------------------
    /// <summary>
    /// Implementation of the action command infrastructure
    /// </summary>
    /// -------------------------------------------------------------------------------------------
    public class ActionCommandBase : INotifyPropertyChanged, ICommand
    {
        // -- Members -----------------------------------------------------------------------------
        private bool isEnabled = true;


        /// ---------------------------------------------------------------------------------------
        /// <summary>
        /// Eventhandler if a property has been changed
        /// </summary>
        /// ---------------------------------------------------------------------------------------
        public event PropertyChangedEventHandler PropertyChanged;

        /// ---------------------------------------------------------------------------------------
        /// <summary>
        /// Eventhandler if the command state has changed
        /// </summary>
        /// ---------------------------------------------------------------------------------------
        public event EventHandler CanExecuteChanged;


        /// ---------------------------------------------------------------------------------------
        /// <summary>
        /// Constructor of this class
        /// </summary>
        /// ---------------------------------------------------------------------------------------
        protected ActionCommandBase()
        {
        }

        /// ---------------------------------------------------------------------------------------
        /// <summary>
        /// Gets or sets a value indicating whether enabled is set
        /// </summary>
        /// ---------------------------------------------------------------------------------------
        public bool IsEnabled
        {
            get
            {
                return this.isEnabled;
            }

            set
            {
                if (this.isEnabled != value)
                {
                    this.isEnabled = value;
                    if (this.CanExecuteChanged != null)
                    {
                        this.CanExecuteChanged(this, EventArgs.Empty);
                    }
                    this.OnPropertyChanged(() => this.IsEnabled);
                }
            }
        }

        /// ---------------------------------------------------------------------------------------
        /// <summary>
        /// Checks if the command can be executed
        /// </summary>
        /// ---------------------------------------------------------------------------------------
        /// <returns>
        /// Returns true if the command is available
        /// </returns>
        /// ---------------------------------------------------------------------------------------
        public bool CanExecute()
        {
            return this.isEnabled;
        }

        /// ---------------------------------------------------------------------------------------
        /// <summary>
        /// Checks if the command can be executed
        /// </summary>
        /// ---------------------------------------------------------------------------------------
        /// <param name="parameter">
        /// Optional parameter of the command
        /// </param>
        /// ---------------------------------------------------------------------------------------
        /// <returns>
        /// Returns true if the command is available
        /// </returns>
        /// ---------------------------------------------------------------------------------------
        public bool CanExecute(object parameter)
        {
            return this.isEnabled;
        }

        /// ---------------------------------------------------------------------------------------
        /// <summary>
        /// This method is called to execute a command
        /// </summary>
        /// ---------------------------------------------------------------------------------------
        /// <param name="parameter">
        /// Optional parameter of the command
        /// </param>
        /// ---------------------------------------------------------------------------------------
        public virtual void Execute(object parameter)
        {
            throw new NotImplementedException();
        }

        /// ---------------------------------------------------------------------------------------
        /// <summary>
        /// Fires the property changed event
        /// </summary>
        /// ---------------------------------------------------------------------------------------
        /// <param name="propName">
        /// Name of the property
        /// </param>
        /// ---------------------------------------------------------------------------------------
        protected void OnPropertyChanged(string propName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
            }
        }

        /// ---------------------------------------------------------------------------------------
        /// <summary>
        /// Fires the property changed event
        /// </summary>
        /// <typeparam name="TResult">Type of expression</typeparam>
        /// ---------------------------------------------------------------------------------------
        /// <param name="propertyExtension">
        /// Name of the property
        /// </param>
        /// ---------------------------------------------------------------------------------------
        protected void OnPropertyChanged<TResult>(Expression<Func<TResult>> propertyExtension)
        {
            if (this.PropertyChanged != null)
            {
                    this.OnPropertyChanged(((MemberExpression)propertyExtension.Body).Member.Name);
            }
        }

        /// <summary>
        /// Gets or sets an arbitrary object value that can be used to store custom information
        /// about this command.
        /// </summary>
        public object Tag { get; set; }
    }
}
